package com.songlanyun.common.utils.yunxin;

import com.songlanyun.common.utils.HttpClientUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 网易云信im即时通信工具类
 */
@Slf4j
@Component
public class YunXinImUtils {

    @Value("${im.AppSecret:1}")
    private String appSecret;

    @Value("${im.AppKey:1}")
    private String appKey;


    public static String sha1Hash(String appSecret, String nonce, String curTime) {
        try {
            // 拼接字符串
            String combinedString = appSecret + nonce + curTime;

            // 获取SHA1实例
            MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");

            // 进行哈希计算
            byte[] hashBytes = messageDigest.digest(combinedString.getBytes());

            // 将结果转换为16进制小写字符串
            StringBuilder hexString = new StringBuilder();
            for (byte b : hashBytes) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) {
                    hexString.append('0');
                }
                hexString.append(hex);
            }

            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

    public static String generateNonce() {
        SecureRandom random = new SecureRandom();
        StringBuilder nonce = new StringBuilder();
        String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

        for (int i = 0; i < 16; i++) {
            int index = random.nextInt(characters.length());
            nonce.append(characters.charAt(index));
        }

        return nonce.toString();
    }

    public static void main(String[] args) {
        String nonce = generateNonce();

        // 获取当前 UTC 时间戳
        String curTime = String.valueOf(Instant.now().getEpochSecond());

        String sign = sha1Hash("8f78aa1bb14a", nonce, curTime);

        log.info("curTime:" + curTime);
        log.info("sign:" + sign);
        log.info("nonce:" + nonce);
    }

    // 网易云im即时通信加密方法
    public YunXinSHADTO sign() {
        YunXinSHADTO dto = new YunXinSHADTO();

        // 生成16位随机字符串nonce
        String nonce = generateNonce();

        // 获取当前 UTC 时间戳
        String curTime = String.valueOf(Instant.now().getEpochSecond());

        String sign = sha1Hash(appSecret, nonce, curTime);

        dto.setSign(sign);
        dto.setNonce(nonce);
        dto.setCurTime(curTime);
        dto.setAppKey(appKey);
        dto.setAppSecret(appSecret);

        return dto;
    }

    public static String convertJsonToUrlEncoded(String jsonString) {
        JSONObject jsonObject = JSONObject.parseObject(jsonString);

        // 准备列表存储参数
        List<String> params = new ArrayList<>();

        try {
            // 遍历JSON对象
            for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue().toString();

                // 进行URL编码并添加到列表中
                params.add(URLEncoder.encode(key, "UTF-8") + "=" + URLEncoder.encode(value, "UTF-8"));
            }

            // 将列表中的参数用 '&' 符号连接起来
            return String.join("&", params);
        } catch (UnsupportedEncodingException e) {
            return null;
        }
    }

    /**
     * 网易云信调用方法
     */
    public JSONObject client(JSONObject req, String url) {
        YunXinSHADTO yunXinSHADTO = sign();

        log.info("网易云信调用入参:" + req.toJSONString());
        log.info("网易云信调用加密参数:" + JSONObject.toJSONString(yunXinSHADTO));
        log.info("网易云信密钥: appKey:{}, appSecret:{}", appKey, appSecret);

        // 参数转换
        String paramStr = convertJsonToUrlEncoded(req.toJSONString());

        HttpClientUtil instance = HttpClientUtil.getInstance();
        String result = instance.imSendHttpPost(url, paramStr, yunXinSHADTO.getNonce(),
                yunXinSHADTO.getCurTime(), yunXinSHADTO.getSign(), yunXinSHADTO.getAppKey());

        log.info("网易云信调用出参:" + result);

        if (StringUtils.isNotBlank(result) && JSONObject.parseObject(result).getInteger("code") == 200){
            JSONObject res = JSONObject.parseObject(result);
            return res;
        } else if (JSONObject.parseObject(result).getInteger("code") != 200) {
            JSONObject res = JSONObject.parseObject(result);
            throw new RuntimeException(res.getString("code") + "-" + res.getString("msg"));
        } else {
            throw new RuntimeException("调用失败");
        }

    }


}
